package com.loong.android.tools;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;

import java.io.ByteArrayOutputStream;

/**
 * 位图工具类，操作Bitmap数据类型
 */
public class BitmapUtils {

    /**
     * 创建位图
     *
     * @param width  位图宽度
     * @param height 位图高度
     */
    public static Bitmap create(int width, int height) {
        return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    }

    /**
     * 位图转字节数组
     *
     * @param bitmap 位图数据
     */
    public static byte[] toBytes(Bitmap bitmap) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
        return bos.toByteArray();
    }

    /**
     * 将字节数组转为位图
     *
     * @param bytes 字节数组
     */
    public static Bitmap fromBytes(byte[] bytes) {
        if (bytes == null || bytes.length <= 0) return null;
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    /**
     * 从字节数组指定位置开始截取转为位图
     *
     * @param bytes  字节数组
     * @param offset 偏移量
     */
    public static Bitmap fromBytes(byte[] bytes, int offset) {
        if (bytes == null || bytes.length <= 0) return null;
        return BitmapFactory.decodeByteArray(bytes, offset, bytes.length);
    }

    /**
     * 从字节数组指定位置开始截取转为位图，并设置最大宽度和高度限制
     *
     * @param bytes     字节数组
     * @param offset    偏移量
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     */
    public static Bitmap fromBytes(byte[] bytes, int offset, int maxWidth, int maxHeight) {
        if (bytes.length == 0) return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(bytes, offset, bytes.length, options);
        options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(bytes, offset, bytes.length, options);
    }

    /**
     * 通过图片文件转为位图
     * 注意：需要先获得读取文件权限(READ_EXTERNAL_STORAGE)
     *
     * @param filePath 文件路径
     */
    public static Bitmap fromFile(String filePath) {
        if (filePath == null || filePath.length() <= 0) return null;
        return BitmapFactory.decodeFile(filePath);
    }

    /**
     * 通过图片文件转为位图，并设置最大宽度和高度限制
     * 注意：需要先获得读取文件权限(READ_EXTERNAL_STORAGE)
     *
     * @param filePath  文件路径
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     */
    public static Bitmap fromFile(String filePath, int maxWidth, int maxHeight) {
        if (filePath == null || filePath.length() <= 0) return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }

    /**
     * 通过资源图片的id转为位图
     *
     * @param context 上下文
     * @param id      资源id
     */
    public static Bitmap fromResource(Context context, int id) {
        if (context == null) return null;
        Resources resources = context.getResources();
        if (resources == null) return null;
        return BitmapFactory.decodeResource(resources, id);
    }

    /**
     * 通过资源图片的id转为位图，并设置最大宽度和高度限制
     *
     * @param context   上下文
     * @param id        资源id
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @return bitmap
     */
    public static Bitmap fromResource(Context context, int id, int maxWidth, int maxHeight) {
        if (context == null) return null;
        Resources resources = context.getResources();
        if (resources == null) return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(resources, id, options);
        options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(resources, id, options);
    }

    /**
     * 取位图宽度
     *
     * @param bitmap 位图
     */
    public static int getWidth(Bitmap bitmap) {
        return bitmap.getWidth();
    }

    /**
     * 取位图高度
     *
     * @param bitmap 位图
     */
    public static int getHeight(Bitmap bitmap) {
        return bitmap.getHeight();
    }

    /**
     * 设置宽度，需要android api>=19才能使用
     * @param bitmap 位图数据
     * @param w 宽度值
     */
    public static void setWidth(Bitmap bitmap, int w) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            bitmap.setWidth(w);
        }
    }

    /**
     * 设置高度，需要android api>=19才能使用
     * @param bitmap 位图数据
     * @param h 高度值
     */
    public static void setHeight(Bitmap bitmap, int h) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            bitmap.setHeight(h);
        }
    }

    /**
     * 取位图字节总长度
     *
     * @param bitmap 位图
     */
    public static int getByteCount(Bitmap bitmap) {
        return bitmap.getByteCount();
    }

    /**
     * 判断位图释放已被释放回收
     *
     * @param bitmap 位图
     */
    public static boolean isRecycled(Bitmap bitmap) {
        return bitmap.isRecycled();
    }

    /**
     * 释放位图数据，让相同回收。当位图被创建后，系统不会自动回收位图，创建大量的位图数据有可能造成内存溢出，
     * 当位图使用完毕后，可通过本函数主动释放位图数据的内存，防止内存溢出。
     *
     * @param bitmap 位图
     */
    public static void recycle(Bitmap bitmap) {
        bitmap.recycle();
    }

    /**
     * 提取透明通道的位图数据
     *
     * @param bitmap 位图
     */
    public static Bitmap getAlpha(Bitmap bitmap) {
        return bitmap.extractAlpha();
    }

    /**
     * 复制位图数据，生成新的位图
     *
     * @param bitmap 位图数据
     * @param isMutable 是否可变
     */
    public static Bitmap copy(Bitmap bitmap, boolean isMutable) {
        return bitmap.copy(Bitmap.Config.ARGB_8888, isMutable);
    }

    /**
     * 位图是否可变
     *
     * @param bitmap 位图数据
     */
    public static boolean isMutable(Bitmap bitmap) {
        return bitmap.isMutable();
    }

    /**
     * 清除位图底色
     *
     * @param bitmap 位图
     * @param color  颜色值
     */
    public static void clearColor(Bitmap bitmap, int color) {
        bitmap.eraseColor(color);
    }

    /**
     * 取位图某一坐标点的颜色值
     * @param bitmap 位图数据
     * @param x 横坐标
     * @param y 横坐标
     */
    public static int getPixel(Bitmap bitmap, int x, int y) {
        return bitmap.getPixel(x, y);
    }

    /**
     * 设置位图某一坐标点的颜色值
     * @param bitmap 位图数据
     * @param x 横坐标
     * @param y 横坐标
     * @param color 颜色值
     */
    public static void setPixel(Bitmap bitmap, int x, int y, int color) {
        bitmap.setPixel(x, y, color);
    }

    /**
     * 计算采样大小
     *
     * @param options   选项
     * @param maxWidth  最大宽度
     * @param maxHeight 最大高度
     * @return 采样大小
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int maxWidth, int maxHeight) {
        if (maxWidth == 0 || maxHeight == 0) return 1;
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;
        while ((height >>= 1) >= maxHeight && (width >>= 1) >= maxWidth) {
            inSampleSize <<= 1;
        }
        return inSampleSize;
    }

}
